﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Facebook.Rest;
using Facebook.Utility;
using CityLife.Objects;
using Facebook.Schema;
using System.Windows.Media.Imaging;
using System.IO.IsolatedStorage;
using CityLife.Classes;
using System.IO;
using FluxJpeg.Core;
using FluxJpeg.Core.Encoder;
using CityLife.Classes.Shader;

namespace CityLife.Controls
{
    public partial class Recorder : FloatableWindow
    {

        public user SelectedUser;
        private CaptureSource _capture;
        private RecorderViewModel _viewModel;
        private IsolatedStorageFile _isf;
        private SaveFileDialog _saveFileDlg;


        public Recorder()
        {
            InitializeComponent();
            this.Loaded+=new RoutedEventHandler(Recorder_Loaded);
        }


        private void rectVideo_MouseLeftButton(object sender, MouseButtonEventArgs e)
        {
           
            if (_capture != null)
            {
                _capture.Stop();

                _capture.VideoCaptureDevice = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();

                VideoBrush videoBrush = new VideoBrush();
                videoBrush.Stretch = Stretch.Uniform;
                videoBrush.SetSource(_capture);
                rectVideo.Fill = videoBrush;


                _capture.CaptureFailed += new EventHandler<ExceptionRoutedEventArgs>(_capture_CaptureFailed);
                _capture.CaptureImageCompleted += new EventHandler<CaptureImageCompletedEventArgs>(_capture_CaptureImageCompleted);
                if (CaptureDeviceConfiguration.AllowedDeviceAccess || CaptureDeviceConfiguration.RequestDeviceAccess())
                {
                    _capture.Start();
                }
            }
        }

        void _capture_CaptureImageCompleted(object sender, CaptureImageCompletedEventArgs e)
        {
             
        }

        void _capture_CaptureFailed(object sender, ExceptionRoutedEventArgs e)
        {
            
        }

        void Recorder_Loaded(object sender, RoutedEventArgs e)
        {
            //instantiate our CaptureSource
            _capture = new CaptureSource();
           
            //get access to issolated storage so we can store a copy of the capture
            _isf = IsolatedStorageFile.GetUserStoreForApplication();





            //when a user right clicks on an image in the wrap panel we are going to allow them to
            //store it to the file system.
            _saveFileDlg = new SaveFileDialog
            {
                DefaultExt = ".jpg",
                Filter = "JPEG Images (*jpeg *.jpg)|*.jpeg;*.jpg",
            };

            //since we declared our ViewModel in xaml i will pull  reference from the controls resources
            _viewModel = Resources["RecorderViewModel"] as RecorderViewModel;


            //load up the list from issolated storage
            string[] names = _isf.GetFileNames("*.jpg");
            foreach (string name in names)
            {
                using (IsolatedStorageFileStream isfs = new IsolatedStorageFileStream(name, FileMode.Open, _isf))
                {
                    BitmapImage image = new BitmapImage();
                    image.SetSource(isfs);
                    WriteableBitmap writeableBitmap = new WriteableBitmap(image);
                    //_viewModel.Captures.Add(new Capture() { Name = name, Bitmap = writeableBitmap });
                }
            }
            _viewModel.Captures.Clear();

        }



        private void Capture_Click(object sender, RoutedEventArgs e)
        {
            if (_capture != null)
            {
                //This approach is effective if you are not applying an effect to the image, but
                //if you are we will need to capture a writableBitmap directly from the destination 
                //of our video brush.

               // _capture.CaptureImageAsync((capturedImage) => _viewModel.Captures.Add(capturedImage));

                try
                {
                    WriteableBitmap writeableBitmap = new WriteableBitmap(rectVideo, null);
                    string name = Guid.NewGuid().ToString() + ".jpg";

                    //store the image in a collection in my viewmodel
                    _viewModel.Captures.Add(new Capture() { Name = name, Bitmap = writeableBitmap });

                    using (IsolatedStorageFileStream isfs = new IsolatedStorageFileStream(name, FileMode.CreateNew, _isf))
                    {
                        MemoryStream stream = new MemoryStream();
                        Recorder.EncodeJpeg(writeableBitmap,stream);
                        stream.CopyTo(isfs);
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Error saving snapshot", MessageBoxButton.OK);
                }
            }
        }



        private void Effect_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            Rectangle rec = sender as Rectangle;
            switch (rec.Name)
            {
                case "invert":
                    var invert = new InvertColorEffect();
                    rectVideo.Effect = invert;
                    break;
                case "mono":
                    var mono = new MonochromeEffect();
                    mono.FilterColor = Colors.White;
                    rectVideo.Effect = mono;
                    break;
                case "swirl":
                    var swirl = new SwirlEffect();
                    swirl.SwirlStrength = 2.5;
                    rectVideo.Effect = swirl;
                    break;
                case "tone":
                    var tone = new ColorToneEffect();
                    tone.Toned = 2;
                    tone.LightColor = Colors.Brown;
                    rectVideo.Effect = tone;
                    break;
                case "emboss":
                    var emboss = new EmbossedEffect();
                    emboss.Amount = 15;
                    emboss.Width = .01;
                    rectVideo.Effect = emboss;
                    break;
                default:
                    rectVideo.Effect = null;
                    break;
            }
        }

     



        private void Button_Click(object sender, RoutedEventArgs e)
        {
            //Capture capture = listImages.SelectedItem as Capture;
            //if (capture != null)
            //{
            //    if (_saveFileDlg.ShowDialog().Value)
            //    {
            //        using (Stream stream = _saveFileDlg.OpenFile())
            //        {
            //            if (_isf.FileExists(capture.Name))
            //            {
            //                using (IsolatedStorageFileStream isfs = new IsolatedStorageFileStream(capture.Name, FileMode.Open, _isf))
            //                {
            //                    isfs.Seek(0, SeekOrigin.Begin);
            //                    isfs.CopyTo(stream);
            //                }
            //            }
            //        }
            //    }
            //}
        }


        

        public static void EncodeJpeg(WriteableBitmap bitmap, MemoryStream stream, int quality = 90)
        {
            int width = bitmap.PixelWidth;
            int height = bitmap.PixelHeight;
            int bands = 3;
            byte[][,] raster = new byte[bands][,];
            for (int i = 0; i < bands; i++)
            {
                raster[i] = new byte[width, height];
            }
            for (int row = 0; row < height; row++)
            {
                for (int column = 0; column < width; column++)
                {
                    int pixel = bitmap.Pixels[width * row + column];
                    raster[0][column, row] = (byte)(pixel >> 16); //R
                    raster[1][column, row] = (byte)(pixel >> 8);  //G
                    raster[2][column, row] = (byte)pixel;         //B
                }
            }
            ColorModel model = new ColorModel { colorspace = ColorSpace.RGB };
            FluxJpeg.Core.Image img = new FluxJpeg.Core.Image(model, raster);

            JpegEncoder encoder = new JpegEncoder(img, quality, stream);
            encoder.Encode();

            stream.Seek(0, SeekOrigin.Begin);

        }
  

        private void OKButton_Click(object sender, RoutedEventArgs e)
        {

            this.DialogResult = true;
        }

        private void CancelButton_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = false;
        }

     
    }
}

